from fastapi import APIRouter, UploadFile
from ..model.master import Material, Lot
import json
from ..utils.database import SessionLocal
from ..utils.post_item import NewMaterialItem, DeleteMaterialItem, AllMaterialItem
from ..utils.ids import datetime_8
import shutil
import os, stat
from ..config import material_dir, Config
from ..utils.file import imgType_list
from pathlib import Path
from sqlalchemy import func
from datetime import timedelta

router = APIRouter()



# 判断料号名是否已存在
@router.get('/check')
async def check(name: str):
    with SessionLocal() as session:
        material = session.query(Material).filter_by(material_name=name, del_flag='0').first()

        if material:
            return {"msg": "料号名已存在, 请重新输入", "code": 1}
        else:
            return {"code": 0}


# 新建料号，并生成 ini 配置文件
@router.post('/new')
async def new(img_file: UploadFile, item: NewMaterialItem):
   
    material = item.material

    suffix = Path(img_file.filename).suffix[1:]

    # 判断是否是 zip 文件, 如果不是返回提示信息
    if suffix not in imgType_list:
        return {"msg": "上传的图片格式不正确，请上传图像格式的文件", "code": 1}
    
    material_name = material["material_name"]
    comment = material.get("comment", "")
    parameter = material["parameter"]

    # 将上传的图片保存到本地
    img_path = f"{material_dir}/{material_name}/PowerOff.bmp"
    # 保存配置文件的路径
    ini_path = f"{material_dir}/{material_name}/parameter.ini"
    # 创建目录
    os.makedirs(f"{material_dir}/{material_name}", exist_ok=True)

    # 将配置信息写入到配置文件
    config = Config()
    for section, values in parameter.items():
        config[section] = values

    with open(ini_path, 'w') as configfile:
        config.write((configfile))

    try:
        with open(img_path, "wb") as buffer:
            shutil.copyfileobj(img_file.file, buffer)
    finally:
        # 保存上传的文件后，我们需要关闭文件以释放资源
        img_file.file.close()

    with SessionLocal() as session:
   
        material = Material(material_name=material_name, background_image=img_path, parameter=json.dumps(parameter), comment=comment)

        session.add(material)
        session.commit()

    return {"msg": "添加料号成功", "code": 0}


# 复制料号
@router.get('/copy')
async def copy(material_code: str):
    with SessionLocal() as session:
        material = session.query(Material).filter_by(material_code=material_code).first()

        parameter = material.material
    return parameter


# 修改料号
@router.post('/modify')
async def modify(material_code: str, item: NewMaterialItem, img_file: UploadFile=None):
    material = item.material
    material_name = material["material_name"]
    comment = material.get("comment", "")
    parameter = material["parameter"]
    img_path = None

    with SessionLocal() as session:
        material_obj = session.query(Material).filter_by(material_code=material_code).first()

        # 重命名目录，按照新的 material_name 命名
        shutil.move(f"{material_dir}/{material_obj.material_name}", f"{material_dir}/{material_name}")

        material_obj.material_name = material_name
        material_obj.comment = comment
        material_obj.parameter = json.dumps(parameter)
        material_obj.update_time = datetime_8()

        session.commit()

    # 如果上传了图片，则修改之前的图片，如果没上传则不做修改
    if img_file:
        suffix = Path(img_file.filename).suffix[1:]

        # 判断是否是 zip 文件, 如果不是返回提示信息
        if suffix not in imgType_list:
            return {"msg": "上传的图片格式不正确，请上传图像格式的文件", "code": 1}
    
        # 将上传的图片保存到本地
        img_path = f"{material_dir}/{material_name}/PowerOff.bmp"
        # 创建目录
        os.makedirs(f"{material_dir}/{material_name}", exist_ok=True)

        try:
            with open(img_path, "wb") as buffer:
                shutil.copyfileobj(img_file.file, buffer)
        finally:
            # 保存上传的文件后，我们需要关闭文件以释放资源
            img_file.file.close()

    # 保存配置文件的路径
    ini_path = f"{material_dir}/{material_name}/parameter.ini"

    # 将配置信息写入到配置文件
    config = Config()
    for section, values in parameter.items():
        config[section] = values

    with open(ini_path, 'w') as configfile:
        config.write((configfile))

    return {"msg": "修改料号成功", "code": 0}


# 删除料号
@router.post('/delete')
async def delete(item: DeleteMaterialItem):
    material_codes = item.material_codes

    with SessionLocal() as session:
        for material_code in material_codes:
            meterial = session.query(Material).filter_by(material_code=material_code).first()
            material_name = meterial.material_name
            material_folder = f"{material_dir}/{material_name}"
            # 删除文件夹
            shutil.rmtree(material_folder)
            # 删除表数据
            session.delete(meterial)

        session.commit()

    return {"msg": "删除料号成功", "code": 0}

    
# 展示所有料号
@router.post('/all')
async def all(item: AllMaterialItem):
    material_name = item.material_name
    start_time = item.start_time
    end_time = item.end_time
    page_index = item.page_index
    page_size = item.page_size
    server_hosts = item.server_hosts

    offset_data = page_size * (page_index-1)

    materials = []
    with SessionLocal() as session:
        all_material = session.query(Material).filter_by(del_flag='0')

        if material_name:
            all_material = all_material.filter(Material.material_name.like("%" + material_name + "%"))

        if start_time:            
            all_material = all_material.filter(Material.create_time.between(start_time, end_time))

        if server_hosts:
            all_material = all_material.filter(Material.server_host.in_(server_hosts))

        total_num = len(all_material.all())
        
        all_material = all_material.order_by(Material.create_time.desc()).offset(offset_data).limit(page_size)

        for material in all_material:
            item = {}
            item["material_code"] = material.material_code
            item["comment"] = material.comment
            item["material_name"] = material.material_name
            # item["background_image"] = material.background_image
            item["create_time"] = material.create_time.strftime('%Y-%m-%d %H:%M:%S')
            item["server_host"] = material.server_host
            item["parameter"] = json.loads(material.parameter)
            item["failure_map"] = json.loads(material.failure_map) if material.failure_map else ""
            lot_num = session.query(func.count(Lot.id)).filter(Lot.material_code.like("%" + material.material_code + "%")).scalar()
            item["lot_num"] = lot_num

            materials.append(item)

    return {"materials": materials, "total_num": total_num}

    

    